package com.modernyuanshiren;

import java.util.List;
import java.util.stream.Collectors;

@SuppressWarnings("rawtypes")
public abstract class AbstractStatus<T extends AbstractStatus<T, U>, U extends ISingleAction<T, U>>
		implements IStatus<T, U> {
	private List<IElement> elements;

	protected void setElements(List<IElement> elements) {
		this.elements = elements;
	}

	@Override
	public List<IElement> getAllElements() {
		return elements;
	}

	protected abstract List<List<IElement>> getAllElementCombinations();

	protected abstract List<U> getAllSingleActions();

	@SuppressWarnings("unchecked")
	@Override
	public List<IAction<T, U>> getAvailableActions() {
		return getAllElementCombinations()
				.stream()
				.flatMap(
						elements -> {
							List<IAction<T, U>> list = getAllSingleActions()
									.stream()
									.filter(a -> a.acceptable((T) this,
											elements))
									.map(res -> createAction(elements, res))
									.collect(Collectors.toList());
							return list.stream();
						}).collect(Collectors.toList());
	}

	protected abstract IAction<T, U> createAction(List<IElement> elements,
			U singleAction);

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result
				+ ((elements == null) ? 0 : elements.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		AbstractStatus other = (AbstractStatus) obj;
		if (elements == null) {
			if (other.elements != null)
				return false;
		} else if (!elements.equals(other.elements))
			return false;
		return true;
	}

}
